<script setup lang="ts">
import { computed, inject, provide, ref, watch, onMounted } from 'vue'
import SingleViewer from '@renderer/views/imgViewer/components/SingleViewer.vue'
import {
  allViewType,
  EnumAllViewType,
  multiViewType,
  resizeViewType,
  loadImgMprType,
  EnumOpTypes,
  opMsgType
} from '@renderer/views/imgViewer/imgTypes'
import OpBtnContainer from '@renderer/views/imgViewer/components/opBtn/OpBtnContainer.vue'
import { useWatchMprAspectChange } from '@renderer/views/imgViewer/mpr/useWatchAspectChange'
import axios from 'axios'
import { useRouter } from 'vue-router'
import { useActiveView } from '@renderer/views/imgViewer/hooks/useActiveView'
import { useViewerStatus } from '@renderer/views/imgViewer/useViewerStatus'
import MipDrawer from '@renderer/views/imgViewer/mpr/MipDrawer.vue'
import PhaseChoose from '@renderer/views/imgViewer/components/PhaseChoose.vue'
import { useGlobalLoading } from '@renderer/utils/useGlobalLoading'

const { showLoading, hideLoading } = useGlobalLoading()
const { ioInstance, sendMsg, baseUri, throughGatewayFlag } = inject('pyImgHandlerIo') as any

onMounted(() => {
  showLoading('加载MPR 影像中...')
})

const mipRef = ref({
  showMipDrawer: false
})
const phaseInfoRef = ref<any>({
  current: 1,
  total: 1
})
const router = useRouter()

const { activeView: activeViewTypeRef, setActiveView: setActiveViewType } = useActiveView('mpr')

provide('windowId', 'mpr')
provide('viewType', EnumAllViewType.mpr)
provide('activeViewType', activeViewTypeRef)
provide('phaseInfo', phaseInfoRef)

const mprImgSrc = ref({
  ax: '',
  sag: '',
  cor: ''
})

const mprCenterRef = ref({
  ax: {
    position: [],
    color: {
      h_color: '',
      v_color: ''
    },
    mip: {
      delta_x: 0,
      delta_y: 0
    }
  },
  sag: {
    position: [],
    color: {
      h_color: '',
      v_color: ''
    },
    mip: {
      delta_x: 0,
      delta_y: 0
    }
  },
  cor: {
    position: [],
    color: {
      h_color: '',
      v_color: ''
    },
    mip: {
      delta_x: 0,
      delta_y: 0
    }
  }
})
const fourCornerInfoRef = ref({})
const statusRef = ref({
  isWaitingFirst3Img: true, // 是否加载了第一次的三视图？
  isFirstShowFullScreen: false, // 是否已经显示过全屏？ 显示过则已经加载了全屏的组件
  isFullScreen: false // 当前是否是全屏状态
})

const measureRef = ref({
  ax: undefined,
  sag: undefined,
  cor: undefined
})

const setMprSize = async (msg: loadImgMprType) => {
  const prefix = throughGatewayFlag ? `${baseUri}/image/` : `${baseUri}/`
  await axios.post(`${prefix}setSize`, msg)
}

const mprAspectsRef = ref()

const initSetMprSize = (mprAspects) => {
  const msg: loadImgMprType = {
    viewType: EnumAllViewType.mpr,
    opType: EnumOpTypes.getImg,
    size: {
      sag: mprAspects[EnumAllViewType.sag],
      cor: mprAspects[EnumAllViewType.cor],
      ax: mprAspects[EnumAllViewType.ax]
    }
  }
  setMprSize(msg)
}

const sendResizeMpr = (mprAspects) => {
  const msg = {
    viewType: EnumAllViewType.mpr,
    opType: 'resize',
    size: mprAspects
  }
  sendMsg(msg)
}

const onMprSizeGotCb = (mprAspects) => {
  mprAspectsRef.value = mprAspects
  if (statusRef.value.isWaitingFirst3Img) {
    initSetMprSize(mprAspects)
    statusRef.value.isWaitingFirst3Img = false
  } else {
    sendResizeMpr(mprAspects)
  }
}

const refresh = () => {
  const mprAspects = mprAspectsRef.value
  const msg: loadImgMprType = {
    viewType: EnumAllViewType.mpr,
    opType: EnumOpTypes.getImg,
    size: {
      sag: mprAspects[EnumAllViewType.sag],
      cor: mprAspects[EnumAllViewType.cor],
      ax: mprAspects[EnumAllViewType.ax]
    }
  }
  setMprSize(msg)
}

const { setAspect } = useWatchMprAspectChange(onMprSizeGotCb)

const axImgSrc = computed(() => {
  return mprImgSrc?.value?.ax
})
const sagImgSrc = computed(() => {
  return mprImgSrc?.value?.sag
})
const corImgSrc = computed(() => {
  return mprImgSrc?.value?.cor
})

interface windowEachType {
  viewType: EnumAllViewType
  imgSrc: string | undefined
  ref: string
  position: string
}

const windowArr = computed<windowEachType[]>(() => {
  return [
    {
      viewType: EnumAllViewType.ax,
      imgSrc: axImgSrc.value,
      ref: 'axRef',
      position: 'left1'
    },
    {
      viewType: EnumAllViewType.sag,
      imgSrc: sagImgSrc.value,
      ref: 'sagRef',
      position: 'left2'
    },
    {
      viewType: EnumAllViewType.cor,
      imgSrc: corImgSrc.value,
      ref: 'corRef',
      position: 'right'
    }
  ]
})

const getImgSrcByViewType = (viewType: multiViewType) => {
  const map = {
    ax: axImgSrc.value,
    sag: sagImgSrc.value,
    cor: corImgSrc.value
  }
  return map[viewType]
}

const toggleActiveView = (type: any) => {
  setActiveViewType(type)
}

const handleToggleFullScreen = (viewType) => {
  setActiveViewType(viewType)
  statusRef.value.isFullScreen = !statusRef.value.isFullScreen
  if (statusRef.value.isFullScreen) {
    statusRef.value.isFirstShowFullScreen = true
  }
  clearToggleInfo()
}

const clearToggleInfo = () => {
  mprImgSrc.value = {
    ax: '',
    sag: '',
    cor: ''
  }
  mprCenterRef.value = {
    ax: {
      position: [],
      color: {
        h_color: '',
        v_color: ''
      },
      mip: {
        delta_x: 0,
        delta_y: 0
      }
    },
    sag: {
      position: [],
      color: {
        h_color: '',
        v_color: ''
      },
      mip: {
        delta_x: 0,
        delta_y: 0
      }
    },
    cor: {
      position: [],
      color: {
        h_color: '',
        v_color: ''
      },
      mip: {
        delta_x: 0,
        delta_y: 0
      }
    }
  }
  fourCornerInfoRef.value = {}
}

const getFullScreenAspect = ({ width, height }: { width: number; height: number }) => {
  const msg = {
    viewType: activeViewTypeRef.value,
    opType: 'resize',
    size: {
      [activeViewTypeRef.value]: {
        width: width,
        height: height
      }
    }
  }
  setTimeout(() => {
    sendMsg(msg)
  }, 200)
}

interface ImgType {
  img: string
  center: number[]
  info_layer: any
  measure_layer: any
  phase_info: any
}

ioInstance.on('image', (data: ImgType[]) => {
  hideLoading()
  for (const [k, v] of Object.entries(data)) {
    mprImgSrc.value[k] = v.img
    mprCenterRef.value[k] = v.center
    fourCornerInfoRef.value[k] = v.info_layer
    measureRef.value[k] = v.measure_layer
    phaseInfoRef.value = v.phase_info
  }
})

const goStack = () => {
  router.push({
    name: 'stack'
  })
}

const go3d = () => {
  router.push({
    name: 'volume'
  })
}

const { viewStatusRef } = useViewerStatus(EnumAllViewType.mpr)

const sendFlipMsg = (hor_flip: boolean, ver_flip: boolean) => {
  const msg: opMsgType = {
    viewType: activeViewTypeRef.value,
    opType: 'flip',
    hor_flip,
    ver_flip
  }
  sendMsg(msg)
}

watch(
  viewStatusRef,
  (newVal) => {
    const flip = newVal[activeViewTypeRef.value]
    sendFlipMsg(flip.horFlip, flip.verFlip)
  },
  {
    deep: true
  }
)

const handleRotate = (rotateSubType: string) => {
  const msg: opMsgType = {
    viewType: activeViewTypeRef.value,
    opType: 'rotate',
    subOpType: rotateSubType
  }
  sendMsg(msg)
}

const handleReset = (subResetType: string) => {
  if (subResetType === 'resetAll') {
    const msg: opMsgType = {
      viewType: EnumAllViewType.mpr,
      opType: 'reset',
      subOpType: subResetType
    }
    sendMsg(msg)
  } else {
    const msg: opMsgType = {
      viewType: activeViewTypeRef.value,
      opType: 'reset',
      subOpType: subResetType
    }
    sendMsg(msg)
  }
}
</script>

<template>
  <div class="w-full h-full flex flex-col">
    <div class="flex flex-1">
      <div class="w-[900px] h-[600px]">
        <div v-show="!statusRef.isFullScreen" class="mpr-container w-full h-full">
          <div
            v-for="item in windowArr"
            :class="[
              activeViewTypeRef === item.viewType ? 'active' : 'inactive',
              item.position,
              item.viewType
            ]"
            class="img-operate-container box-border"
            @click="toggleActiveView(item.viewType)"
            :key="item.viewType"
          >
            <single-viewer
              :key="item.viewType"
              @dblclick="handleToggleFullScreen(item.viewType)"
              :view-type="item.viewType"
              :img-src="item.imgSrc"
              :center="mprCenterRef[item.viewType]"
              :fourCornerInfo="fourCornerInfoRef[item.viewType]"
              :measure-info="measureRef[item.viewType]"
              @set-aspect="(args) => setAspect(item.viewType, args)"
            />
          </div>
        </div>
        <div v-if="statusRef.isFirstShowFullScreen && statusRef.isFullScreen" class="w-full h-full">
          <single-viewer
            @dblclick="handleToggleFullScreen(activeViewTypeRef)"
            :img-src="getImgSrcByViewType(activeViewTypeRef as multiViewType)"
            :view-type="activeViewTypeRef as allViewType"
            :center="mprCenterRef[activeViewTypeRef]"
            @set-aspect="(args) => getFullScreenAspect(args)"
            :fourCornerInfo="fourCornerInfoRef[activeViewTypeRef]"
            :measure-info="measureRef[activeViewTypeRef]"
          />
        </div>
      </div>
      <div class="w-[100px] h-[550px] flex flex-col">
        <op-btn-container
          v-model:viewStatus="viewStatusRef[activeViewTypeRef]"
          @rotate="handleRotate"
          @reset="handleReset"
        />
        <el-button class="!ml-0" @click="refresh">refresh</el-button>
        <el-button class="!ml-0" @click="mipRef.showMipDrawer = true">MIP</el-button>
        <el-button class="!ml-0" @click="goStack">Stack View</el-button>
        <el-button class="!ml-0" @click="go3d">3D View</el-button>
      </div>
    </div>

    <div class="h-[30px] w-full">
      <phase-choose />
    </div>
  </div>
  <mip-drawer v-model="mipRef.showMipDrawer" />
</template>

<style scoped>
.mpr-container {
  display: grid;
  grid-template-columns: 2fr 2fr;
  grid-template-rows: 1fr 1fr;
}

.right {
  grid-row-start: 1;
  grid-row-end: 3;
  grid-column-start: 2;
  grid-column-end: 3;
}

.left1,
.left2,
.right {
  border: 4px solid transparent;
  box-sizing: border-box;
  overflow: hidden;
}

.active {
  border: 4px solid cornflowerblue;
}

.inactive {
  border: 4px solid transparent;
}
</style>
`
